package client;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

/**
 * 
 */
class MyGameWindowAdapter extends WindowAdapter {
	public void windowClosing(WindowEvent e) {
		System.exit(0);
	}
}

/**
 * @author papq
 *
 */
public class MainViewJFrame extends JFrame implements Observable {
	private Model model;

	private ArrayList<Observer> observers;

	private boolean changed;

	private TablePanel tablePanel;
	private HandPanel handPanel;
	private MenuPanel menuPanel;
	JTextField answearTextField;
	JButton exchangeButton;

	public MainViewJFrame(Model model) {
		super("Badugi Poker Game");
		this.model = model;
		observers = new ArrayList<Observer>();
		changed = false;

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 50, 800, 655);
		setLayout(null);
		setResizable(false);

		tablePanel = new TablePanel();
		tablePanel.setBounds(15, 15, 600, 300);
		add(tablePanel);

		handPanel = new HandPanel(this, model);
		handPanel.setBounds(10, 360, 630, 220);
		add(handPanel);

		menuPanel = new MenuPanel(this, model);
		menuPanel.setBounds(660, 15, 120, 550);
		add(menuPanel);

		exchangeButton = new JButton("EXCHANGE");
		exchangeButton.setBounds(500, 325, 130, 25);
		exchangeButton.setEnabled(false);
		add(exchangeButton);
		exchangeButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				MainViewJFrame.this.model.setPressedButton("Exchange");
				answearTextField.setText("Waiting for exchange...");
				setChanged();
				notifyObservers();
			}
		});

		answearTextField = new JTextField();
		answearTextField.setBounds(10, 590, 780, 25);
		answearTextField.setEditable(false);
		add(answearTextField);

		// setVisible(true);
	}

	@Override
	public void addObserver(Observer observer) {
		observers.add(observer);
	}

	@Override
	public void removeObserver(Observer observer) {
		observers.remove(observer);
	}

	@Override
	public void notifyObservers() {
		if (changed) {
			for (Observer o : observers) {
				o.updateFromMainView();
			}
			changed = false;
		}
	}

	@Override
	public void setChanged() {
		changed = true;
	}

	public void createGame() {
		menuPanel.setNameLabelText("Player " + model.getPlayerID());
		menuPanel.setBankrollLabelText("BANKROLL: " + model.getBankroll() + "T");
		int nrOfPlayers = Integer.parseInt(model.getPlayersInGame());
		int[] otherPlayerID = new int[nrOfPlayers];
		for (int x = 0; x < nrOfPlayers; x++) {
			otherPlayerID[x] = x;
		}
		int playerID = Integer.parseInt(model.getPlayerID());

		for (int a = 0; a < nrOfPlayers; a++) {
			if (playerID == a) {
				if (nrOfPlayers - 1 == a) {
					// do nothing
				} else if (nrOfPlayers - 2 == a) {
					otherPlayerID[a] = otherPlayerID[a + 1];
				} else if (nrOfPlayers - 3 == a) {
					otherPlayerID[a] = otherPlayerID[a + 1];
					otherPlayerID[a + 1] = otherPlayerID[a + 2];
				} else if (nrOfPlayers - 4 == a) {
					otherPlayerID[a] = otherPlayerID[a + 1];
					otherPlayerID[a + 1] = otherPlayerID[a + 2];
					otherPlayerID[a + 2] = otherPlayerID[a + 3];
				} else if (nrOfPlayers - 5 == a) {
					otherPlayerID[a] = otherPlayerID[a + 1];
					otherPlayerID[a + 1] = otherPlayerID[a + 2];
					otherPlayerID[a + 2] = otherPlayerID[a + 3];
					otherPlayerID[a + 3] = otherPlayerID[a + 4];
				} else if (nrOfPlayers - 6 == a) {
					otherPlayerID[a] = otherPlayerID[a + 1];
					otherPlayerID[a + 1] = otherPlayerID[a + 2];
					otherPlayerID[a + 2] = otherPlayerID[a + 3];
					otherPlayerID[a + 3] = otherPlayerID[a + 4];
					otherPlayerID[a + 4] = otherPlayerID[a + 5];
				}
			}
		}

		for (int i = 0; i < nrOfPlayers - 1; i++) {
			tablePanel.panelPlayer[otherPlayerID[i]].setNameLabelText("Player " + otherPlayerID[i]);
			tablePanel.panelPlayer[otherPlayerID[i]].setBankrollLabelText("Bankroll: " + model.getBankroll() + "T");
		}
	}

	public void setHand() {
		handPanel.setButtonCard0Text(model.getCardName(0));
		handPanel.setButtonCard1Text(model.getCardName(1));
		handPanel.setButtonCard2Text(model.getCardName(2));
		handPanel.setButtonCard3Text(model.getCardName(3));
	}

	public void setDealer(String iDOfPlayerWhoIsDealer) {
		if (iDOfPlayerWhoIsDealer.equals(model.getPlayerID())) {
			menuPanel.setAttributeLabelText("DEALER BUTTON");
		} else {
			tablePanel.panelPlayer[Integer.parseInt(iDOfPlayerWhoIsDealer)]
					.setAttributeLabelText("DEALER BUTTON");
		}
	}

	public void setWhoHasBigBlind(String playerWithBigBlind) {
		if (playerWithBigBlind.equals(model.getPlayerID())) {
			menuPanel.setAttributeLabelText("BIG BLIND");
			menuPanel.setYourBetLabelText("Your bet: " + model.getBigBlind() + "T");
		} else {
			tablePanel.panelPlayer[Integer.parseInt(playerWithBigBlind)]
					.setAttributeLabelText("BIG BLIND");
			tablePanel.panelPlayer[Integer.parseInt(playerWithBigBlind)]
					.setBetValueLabelText("Bet: " + model.getBigBlind() + "T");
			tablePanel.panelPlayer[Integer.parseInt(playerWithBigBlind)]
					.setBankrollLabelText("BANKROLL: "
							+ (Integer.parseInt(model.getBankroll()) - Integer.parseInt(model.getBigBlind())) + "T");
		}
	}

	public void setWhoHasSmallBlind(String playerWithSmallBlind) {
		if (playerWithSmallBlind.equals(model.getPlayerID())) {
			menuPanel.setAttributeLabelText("SMALL BLIND");
			menuPanel.setYourBetLabelText("Your bet: " + model.getSmallBlind() + "T");
		} else {
			tablePanel.panelPlayer[Integer.parseInt(playerWithSmallBlind)]
					.setAttributeLabelText("SMALL BLIND");
			tablePanel.panelPlayer[Integer.parseInt(playerWithSmallBlind)]
					.setBetValueLabelText("Bet: " + model.getSmallBlind() + "T");
			tablePanel.panelPlayer[Integer.parseInt(playerWithSmallBlind)]
					.setBankrollLabelText("BANKROLL: "
							+ (Integer.parseInt(model.getBankroll()) - Integer.parseInt(model.getSmallBlind())) + "T");
		}
	}

	public void displayMaxBet() {
		tablePanel.potPanel.setMaxBetLabelText("MAX BET: " + model.getMaxBetNow() + "T");
	}

	/**
	 * Sets card with index 0 selected to exchange.
	 */
	public void setCard0Selected() {
		handPanel.setButtonCard0Disabled();
		exchangeButton.setEnabled(true);
	}
	/**
	 * Sets card with index 1 selected to exchange.
	 */
	public void setCard1Selected() {
		handPanel.setButtonCard1Disabled();
		exchangeButton.setEnabled(true);
	}
	/**
	 * Sets card with index 2 selected to exchange.
	 */
	public void setCard2Selected() {
		handPanel.setButtonCard2Disabled();
		exchangeButton.setEnabled(true);
	}
	/**
	 * Sets card with index 3 selected to exchange.
	 */
	public void setCard3Selected() {
		handPanel.setButtonCard3Disabled();
		exchangeButton.setEnabled(true);
	}
	/**
	 * Sets all buttonCard[i] enabled - can be clicked. Should be sets when it's player turn to exchange.
	 */
	public void enableCardsExchange() {
		handPanel.setAllButtonCardsEnabled();
		exchangeButton.setEnabled(true);
	}

	/**
	 * Sets all buttonCard[i] disabled - cannot be clicked. Always when it's not
	 * time to exchange.
	 */
	public void disableCardExchange() {
		handPanel.setButtonCard0Disabled();
		handPanel.setButtonCard1Disabled();
		handPanel.setButtonCard2Disabled();
		handPanel.setButtonCard3Disabled();
		exchangeButton.setEnabled(false);
	}
	/**
	 * Displays message on status bar at the bottom of View.
	 * @param contentOfMessage message content
	 */
	public void displayMessage(String contentOfMessage) {
		answearTextField.setText(contentOfMessage);
	}

	/**
	 * Displays player's actual bet and bankroll on menuPanel at right bottom of MainView.
	 * @param contentOfMessage message content
	 */
	public void displayPlayerBetNowAndBankrollNow() {
		menuPanel.setBankrollLabelText("BANKROLL: " + model.getPlayerBankrollNow() + "T");
		menuPanel.setYourBetLabelText("Your bet: " + model.getPlayerBetNow() + "T");
	}

	public void disableBettingButtons() {
		menuPanel.setCheckButtonDisabled();
		menuPanel.setBetTextFieldDisabled();
		menuPanel.setBetButtonDisabled();
		menuPanel.setRaiseTextFieldDisabled();
		menuPanel.setRaiseButtonDisabled();
		menuPanel.setCallButtonDisabled();
		menuPanel.setFoldButtonDisabled();
		menuPanel.setAllInButtonDisabled();
	}

	public void enableBettingButtons() {
		if (model.getPlayerBankrollNow() < model.getMaxBetNow()) {
			menuPanel.setAllInButtonEnabled();
		} else {
			if (model.getPlayerBetNow() == model.getMaxBetNow()) {
				menuPanel.setCheckButtonEnabled();
			}
			if (model.getWasBetPlayed() == false) {
				menuPanel.setBetButtonEnabled();
				menuPanel.setBetTextFieldEnabled();
			}
			if (model.getWasBetPlayed() == true) {
				menuPanel.setRaiseTextFieldEnabled();
				menuPanel.setRaiseButtonEnabled();
			}
			if (model.getPlayerBetNow() != model.getMaxBetNow()) {
				menuPanel.setCallButtonEnabled();
			}
		}
		menuPanel.setFoldButtonEnabled();
	}
	
	public void setPanelPlayerWhoPlayed(String playedAction) {
		switch(playedAction) {
		case "Check":
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setAuctionLabelText("Check");
			//bet without change
			//bankroll without change
			break;
		case "Bet":
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setAuctionLabelText("Bet");
			if (model.getWhoHasSmallBlind().equals(model.getIDOfPlayerWhoPlayed())) {
				tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBetValueLabelText("Bet: " + (model.getBetValueOfPlayerWhoPlayed() + Integer.parseInt(model.getSmallBlind())) + "T");
			} else if (model.getWhoHasBigBlind().equals(model.getIDOfPlayerWhoPlayed())) {
				tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBetValueLabelText("Bet: " + (model.getBetValueOfPlayerWhoPlayed() + Integer.parseInt(model.getBigBlind())) + "T");
			} else {
				tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBetValueLabelText("Bet: " + model.getBetValueOfPlayerWhoPlayed() + "T");
			}
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBetValueLabelText("Bet: " + model.getBetValueOfPlayerWhoPlayed() + "T");
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBankrollLabelText("BANKROLL: " + model.getBankrollOfPlayerWhoPlayed() + "T");
			break;
		case "Raise":
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setAuctionLabelText("Raise");
			if (model.getWhoHasSmallBlind().equals(model.getIDOfPlayerWhoPlayed())) {
				tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBetValueLabelText("Bet: " + (model.getBetValueOfPlayerWhoPlayed() + Integer.parseInt(model.getSmallBlind())) + "T");
			} else if (model.getWhoHasBigBlind().equals(model.getIDOfPlayerWhoPlayed())) {
				tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBetValueLabelText("Bet: " + (model.getBetValueOfPlayerWhoPlayed() + Integer.parseInt(model.getBigBlind())) + "T");
			} else {
				tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBetValueLabelText("Bet: " + model.getBetValueOfPlayerWhoPlayed() + "T");
			}
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBankrollLabelText("BANKROLL: " + model.getBankrollOfPlayerWhoPlayed() + "T");
			break;
		case "Call":
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setAuctionLabelText("Call");
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBetValueLabelText("Bet: " + model.getMaxBetNow() + "T");
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBankrollLabelText("BANKROLL: " + model.getBankrollOfPlayerWhoPlayed() + "T");
			break;
		case "Fold":
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setAuctionLabelText("Fold");
			//bet without change
			//bankroll without change
			break;
		case "All-in":
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setAuctionLabelText("All-in");
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBetValueLabelText("Bet: " + (model.getMaxBetNow()+model.getBetValueOfPlayerWhoPlayed()) + "T");
			tablePanel.panelPlayer[Integer.parseInt(model.getIDOfPlayerWhoPlayed())].setBankrollLabelText("BANKROLL: 0T");
			break;
		}
	}

	/**
	 * Displays actual player bet and bankroll on menuPanel at right bottom of View.
	 */
	public void setMenuPanelAfterBetting() {
		menuPanel.setYourBetLabelText("Your bet: " + model.getPlayerBetNow() + "T");
		menuPanel.setBankrollLabelText("BANKROLL: " + model.getPlayerBankrollNow() + "T");
	}

	/**
	 * Displays actual max bet on table at center of View.
	 */
	public void setPotPanelAfterAction() {
		tablePanel.potPanel.setMaxBetLabelText("MAX BET: " + Integer.toString(model.getMaxBetNow()));
//		tablePanel.potPanel.setPotLabelText(model.getBankroll());
		
	}

	public void setPanelPlayerWhoExchanged() {
		System.out.println("setPanelPlayerWhoExchanged");
		if(!(model.getPlayerIDWhoExchanged().equals(model.getPlayerID()))) {
			tablePanel.panelPlayer[Integer.parseInt(model.getPlayerIDWhoExchanged())].setAuctionLabelText("Exchanged " + model.getNrOfExchangedCards() + " cards.");
		}
	}

	public void displayWinner() {
		if (model.getNumberOfWinners() == 1) {
			if (model.getWinnerID().equals(model.getPlayerID())) {
				menuPanel.setBankrollLabelText("BANKROLL: " + model.getPlayerBankrollNow() + "T");
				answearTextField.setText("Winner!: You won " + model.getWinningAmount() + "T.");
			} else {
				int otherPlayerBankroll = tablePanel.getOtherPlayerBankroll(Integer.parseInt(model.getWinnerID()));
				int winningAmount = Integer.parseInt(model.getWinningAmount());
				tablePanel.panelPlayer[Integer.parseInt(model.getWinnerID())].setBankrollLabelText("BANKROLL: " + (otherPlayerBankroll + winningAmount) + "T");;
				tablePanel.panelPlayer[Integer.parseInt(model.getWinnerID())].setAuctionLabelText("Won " + model.getWinningAmount() + "T.");
				answearTextField.setText("Winner!: Player " + model.getWinnerID() + " won " + model.getWinningAmount() + "T.");
			}
		} else {
			for(int i=0; i<model.getNumberOfWinners(); i++){
				String winnerID = model.getWinnersID().substring(i, i+1);
				answearTextField.setText("Winners!: ");
				if (winnerID.equals(model.getPlayerID())) {
					answearTextField.setText(answearTextField.getText() + "You won " + model.getWinningAmount() + "T. ");
				} else {
					int otherPlayerBankroll = tablePanel.getOtherPlayerBankroll(Integer.parseInt(winnerID));
					int winningAmount = Integer.parseInt(model.getWinningAmount());
					tablePanel.panelPlayer[Integer.parseInt(winnerID)].setBankrollLabelText("BANKROLL: " + (otherPlayerBankroll + winningAmount) + "T");;
					tablePanel.panelPlayer[Integer.parseInt(winnerID)].setAuctionLabelText("Won " + model.getWinningAmount() + "T.");
					answearTextField.setText(answearTextField.getText() + "Player " + winnerID + " won " + model.getWinningAmount() + "T. ");
				}
			}
		}
	}

	public void askClientForNextRound() {
		int reply = JOptionPane.showConfirmDialog(null, "Do you want to play again?", "Badugi Poker Game", JOptionPane.YES_NO_OPTION);
			if (reply == JOptionPane.YES_OPTION) {
				JOptionPane.showMessageDialog(null, "Please wait for other players decision.");
	          	model.setPressedButton("YES");
	          	setChanged();
	          	notifyObservers();
	        }
	        else {
	        	JOptionPane.showMessageDialog(null, "Thanks for game. See you later!");
	        	model.setPressedButton("NO");
	        	setChanged();
	        	notifyObservers();
	        }
	}

	public void informUserThatThereWillNotBeAnotherRound() {
		int input = JOptionPane.showOptionDialog(null, "Other player(s) don't want to play anymore. Thanks for game. See you later!", "Badugi Poker Game", JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null);
		if(input == JOptionPane.OK_OPTION)
		{
        	model.setPressedButton("OK");
        	setChanged();
        	notifyObservers();
		}
        else {
        	model.setPressedButton("CANCEL");
        	setChanged();
        	notifyObservers();
        }
	}

	public void informUserThatSbLoose() {
		int input = JOptionPane.showOptionDialog(null, "Player " + model.getLooserID() + " have lost. Thanks for game. See you later!", "Badugi Poker Game", JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null);
		if(input == JOptionPane.OK_OPTION)
		{
        	model.setPressedButton("OK");
        	setChanged();
        	notifyObservers();
		}
        else {
        	model.setPressedButton("CANCEL");
        	setChanged();
        	notifyObservers();
        }
		// TODO Auto-generated method stub
		
	}
	
	public void setMainViewToDefault() {
		answearTextField.setText("");
		tablePanel.potPanel.setMaxBetLabelText("MAX BET: ");
		menuPanel.setAttributeLabelText("");
		menuPanel.setYourBetLabelText("Your bet: 0T");
		
		int nrOfPlayers = Integer.parseInt(model.getPlayersInGame());
		int[] otherPlayerID = new int[nrOfPlayers];
		for (int x = 0; x < nrOfPlayers; x++) {
			otherPlayerID[x] = x;
		}
		int playerID = Integer.parseInt(model.getPlayerID());

		for (int a = 0; a < nrOfPlayers; a++) {
			if (playerID == a) {
				if (nrOfPlayers - 1 == a) {
					// do nothing
				} else if (nrOfPlayers - 2 == a) {
					otherPlayerID[a] = otherPlayerID[a + 1];
				} else if (nrOfPlayers - 3 == a) {
					otherPlayerID[a] = otherPlayerID[a + 1];
					otherPlayerID[a + 1] = otherPlayerID[a + 2];
				} else if (nrOfPlayers - 4 == a) {
					otherPlayerID[a] = otherPlayerID[a + 1];
					otherPlayerID[a + 1] = otherPlayerID[a + 2];
					otherPlayerID[a + 2] = otherPlayerID[a + 3];
				} else if (nrOfPlayers - 5 == a) {
					otherPlayerID[a] = otherPlayerID[a + 1];
					otherPlayerID[a + 1] = otherPlayerID[a + 2];
					otherPlayerID[a + 2] = otherPlayerID[a + 3];
					otherPlayerID[a + 3] = otherPlayerID[a + 4];
				} else if (nrOfPlayers - 6 == a) {
					otherPlayerID[a] = otherPlayerID[a + 1];
					otherPlayerID[a + 1] = otherPlayerID[a + 2];
					otherPlayerID[a + 2] = otherPlayerID[a + 3];
					otherPlayerID[a + 3] = otherPlayerID[a + 4];
					otherPlayerID[a + 4] = otherPlayerID[a + 5];
				}
			}
		}

		for (int i = 0; i < nrOfPlayers - 1; i++) {
			tablePanel.panelPlayer[otherPlayerID[i]].setAttributeLabelText("");
			tablePanel.panelPlayer[otherPlayerID[i]].setBetValueLabelText("Bet: 0T");
			tablePanel.panelPlayer[otherPlayerID[i]].setAuctionLabelText("");
		}
	}
}
